package org.yyjkcache.common;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis工具类(维持一个redis连接池)
 *
 * @author zhangwei
 */
public class JedisLinkedPool {

    private static JedisLinkedPool handler=new JedisLinkedPool();
    private JedisPool jedisPool;

    // redis连接池初始化
    private JedisLinkedPool() {
        Properties properties = PropertiesHandler.getValueOnRoot("redis.properties");
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(Integer.parseInt(properties.getProperty("redis.maxTotal").trim()));
        config.setMaxIdle(Integer.parseInt(properties.getProperty("redis.maxIdle").trim()));
        config.setMinIdle(Integer.parseInt(properties.getProperty("redis.minIdle").trim()));
        config.setTestOnReturn(Boolean.parseBoolean(properties.getProperty("redis.testOnReturn").trim()));
        config.setTestOnBorrow(Boolean.parseBoolean(properties.getProperty("redis.testOnBorrow").trim()));
        jedisPool = new JedisPool(config, properties.getProperty("redis.url"),
                Integer.parseInt(properties.getProperty("redis.port")), 2000, properties.getProperty("redis.auth"), Integer.valueOf(properties.getProperty("redis.db")).intValue());
    }

    /**
     * 获取jedis对象实例
     *
     * @return
     */
    public Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 对象序列化
     *
     * @param obj
     * @return
     */
    public byte[] objectSerialize(Object obj) {
        ObjectOutputStream oos = null;
        ByteArrayOutputStream bOutputStream = null;
        byte[] b = null;
        try {
            bOutputStream = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bOutputStream);
            oos.writeObject(obj);
            b = bOutputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != bOutputStream) {
                    bOutputStream.close();
                }
                if (null != oos) {
                    oos.close();
                    oos = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return b;
    }

    /**
     * Object反序列化
     *
     * @param bytes
     * @return
     */
    public Object objectDeSerialize(byte[] bytes) {
        ByteArrayInputStream in = null;
        ObjectInputStream objIn = null;
        Object object = null;
        try {
            in = new ByteArrayInputStream(bytes);
            objIn = new ObjectInputStream(in);
            object = objIn.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != in) {
                    in.close();
                }
                if (null != objIn) {
                    objIn.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return object;
    }

    /**
     * 向
     * @param key
     * @param contents
     */
    public void listPush(String key,String[]contents){
        Jedis jedis=getJedis();
        jedis.lpush(key,contents);
        jedis.close();
    }


    /**
     * 保存数据到hash
     *
     * @param key     键
     * @param hashmap hash值
     */
    public void saveObjectToRedis(byte[] key, HashMap<byte[], byte[]> hashmap) {
        Jedis jedis = getJedis();
        jedis.hmset(key, hashmap);
        jedis.close();
    }

    /**
     * 获取hash
     *
     * @param key
     * @param field
     * @return
     */
    public HashMap<String, Object> getHashFromRedis(byte[] key, byte[] field) {
        Jedis jedis = getJedis();
        byte[] b = jedis.hget(key, field);
        @SuppressWarnings("unchecked")
        HashMap<String, Object> hashMap = (HashMap<String, Object>) objectDeSerialize(b);
        jedis.close();
        return hashMap;
    }

    /**
     * 获取所有hash
     *
     * @param b
     * @return
     */
    public Map<byte[], byte[]> getAllHashFromRedis(byte[] b) {
        Jedis jedis = getJedis();
        Map<byte[], byte[]> hmap = jedis.hgetAll(b);
        jedis.close();
        return hmap;
    }

    /**
     * 保存json表数据到redis
     *
     * @param tablename
     * @param hmp
     */
    public void saveJsonDataToRedis(String tablename, HashMap<String, String> hmp) {
        Jedis jedis = getJedis();
        jedis.hmset(tablename, hmp);
        jedis.close();
    }

    /**
     * 获取虚拟表数据
     *
     * @param tablename
     * @return
     */
    public Map<String, String> getVirtualTableData(String tablename) {
        Jedis jedis = getJedis();
        Map<String, String> map = jedis.hgetAll(tablename);
        jedis.close();
        return map;
    }

    /**
     * 获取key所对应的所有list数据
     *
     * @param key 键
     * @return
     */
    public List<String> getAllListValue(String key) {
        Jedis jedis = getJedis();
        if (!jedis.exists(key))
            return null;
        List<String> list = jedis.lrange(key, 0, -1);
        jedis.close();
        return list;
    }

    /**
     * 返回jedis处理器件
     * @return
     */
    public static JedisLinkedPool pool(){
        return handler;
    }
}
